package service

import (
	"echo-utils/internal/dao"
	"fmt"
	"strings"
	"sync"
)

var (
	dbLogerHanlder   *dao.IlogDao
	dbArticleHandler *dao.ArticleDao
)

type FindIniTaskResult struct {
	RWM  sync.RWMutex
	inis []string
}

type FindIniTask struct {
	path   string //需要遍历的目录
	wg     *sync.WaitGroup
	result *FindIniTaskResult
}

func (f FindIniTask) Run() {
	defer f.wg.Done()
	dbLogerHanlder.Add(fmt.Sprintf("扫描目录：%s", f.path))
	ef := NewEchoFile()
	inis := ef.FindSource(f.path)
	for _, ini := range inis {
		f.result.RWM.Lock()
		f.result.inis = append(f.result.inis, ini)
		f.result.RWM.Unlock()
	}
}

type GenSourceItemTask struct {
	ini string //ini
	wg  *sync.WaitGroup
}

func (g GenSourceItemTask) Run() {
	defer g.wg.Done()
	dbLogerHanlder.Add(fmt.Sprintf("处理资源：%s", g.ini))
	ef := NewEchoFile()
	si := NewSourceItem(g.ini, ef)
	article := si.Data()
	if article != nil {
		dbArticleHandler.AddArticle(article)
	}
}

// 资源处理器，接收需要处理的资源路径
type SourceCore struct {
	paths []string
}

func NewSourceCore(paths []string) *SourceCore {
	return &SourceCore{
		paths: paths,
	}
}

func (s *SourceCore) Scan() {
	dbLogerHanlder = dao.NewIlogDao()
	dbArticleHandler = dao.NewArticleDao()
	volidPaths := make([]string, 0)
	//处理路径列表，过滤无效路径
	for _, path := range s.paths {
		ef := NewEchoFile()
		if ef.IsDir(path) {
			volidPaths = append(volidPaths, path)
		}
	}
	result := s.scanWorker(volidPaths) //所有配置文件

	s.dataWorker(result)
	dbLogerHanlder.Clear() //处理完成之后清理数据库日志，该日志仅作为页面显示后台任务用
}

func (s *SourceCore) scanWorker(volidPaths []string) []string {
	var wg sync.WaitGroup
	wg.Add(len(volidPaths))
	scheduler := NewScheduler(MaxWorker)
	scheduler.Create()
	result := &FindIniTaskResult{}
	go s.createIniJobQueue(&wg, volidPaths, result)
	wg.Wait()
	scheduler.Shutdown()
	dbLogerHanlder.Add(fmt.Sprintf("目录扫描完成，找到资源：\n%s", strings.Join(result.inis, "\n")))
	return result.inis
}

func (s *SourceCore) dataWorker(inis []string) {
	var wg sync.WaitGroup
	wg.Add(len(inis))
	scheduler := NewScheduler(MaxWorker)
	scheduler.Create()
	go s.createDataJobQueue(&wg, inis)
	wg.Wait()
	scheduler.Shutdown()
	dbLogerHanlder.Add("资源处理完成")
}

func (s *SourceCore) createIniJobQueue(wg *sync.WaitGroup, paths []string, result *FindIniTaskResult) {
	JobQueue = make(chan Job, MaxWorker)
	for _, path := range paths {
		dbLogerHanlder.Add("创建任务：查找目录-> " + path)
		task := FindIniTask{
			path:   path,
			wg:     wg,
			result: result,
		}
		job := Job{Task: task}
		JobQueue <- job
	}
}

func (s *SourceCore) createDataJobQueue(wg *sync.WaitGroup, paths []string) {
	JobQueue = make(chan Job, MaxWorker)
	for _, path := range paths {
		dbLogerHanlder.Add("创建任务：处理资源-> " + path)
		task := GenSourceItemTask{
			ini: path,
			wg:  wg,
		}
		job := Job{Task: task}
		JobQueue <- job
	}
}
